package it.polimi.entitiesManagers;


import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJBContext;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import it.polimi.authentication.ejb.usermanagement.Group;
import it.polimi.entities.Attraction;
import it.polimi.entities.Flight;
import it.polimi.entities.Hotel;
import it.polimi.entities.Packet;
import it.polimi.entities.PacketAttraction;
import it.polimi.entities.PacketFlight;
import it.polimi.entities.PersonalizedPacket;
import it.polimi.entitiesDTO.PacketDTO;
import it.polimi.entitiesDTO.PacketFlightDTO;

@Stateless
public class PacketManagerBean implements PacketMgr {

	@PersistenceContext
    private EntityManager em;
	
	@Resource
	private EJBContext context;
	
	private int id1;
	
	private int id2;
	
	private int packetID;
	
	@Override
	@RolesAllowed({Group._EMPLOYEE})
	public void save(PacketDTO packet) {
		Hotel hotel = em.createNamedQuery(Hotel.FIND_BY_ID, Hotel.class).setParameter("id", packet.getHotel()).getSingleResult();
		packet.setEmployee(context.getCallerPrincipal().getName());
		Packet newPacket = new Packet(packet, hotel);
		em.persist(newPacket);
		setPacketID(newPacket.getId());
		/*
		PacketFlight pf1 = new PacketFlight(newPacket);
		PacketFlight pf2 = new PacketFlight(newPacket);
		id1 = pf1.getId();
		id2 = pf2.getId();
		 */
		}
	
	
	
	@Override
	@RolesAllowed({Group._EMPLOYEE})
	public void save(PacketFlightDTO packetFlight) {
		PacketFlight pf1 = getPacketFlight(Integer.toString(id1));
		PacketFlight pf2 = getPacketFlight(Integer.toString(id2));
		em.persist(pf1);
		em.persist(pf2);
		}
	
	public void update(PacketDTO packet) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public PacketDTO getPacketDTO() {
		PacketDTO packetDTO = convertToDTO(getPrincipalPacket());
		return packetDTO;
	}
	
	@Override
	public PacketFlightDTO getPacketFlightDTO() {
		PacketFlightDTO packetFlightDTO = convertToDTO(getPrincipalPacketFlight());
		return packetFlightDTO;
	}
	
	public Packet findPacket(String name) {
    	return em.find(Packet.class, name);
    }
	
	public PacketFlight findPacketFlight(String name) {
    	return em.find(PacketFlight.class, name);
    }
	
	public Packet getPrincipalPacket() {
    	return findPacket(getPrincipalName());
    }
	
	public PacketFlight getPrincipalPacketFlight() {
    	return findPacketFlight(getPrincipalName());
    }
	
	public String getPrincipalName() {
    	return context.getCallerPrincipal().getName();
    }
	
	
	public Packet getPacket(String id){
		return em.createNamedQuery(Packet.FIND_PACKET, Packet.class).setParameter("id", id).getSingleResult();
	}
	
	public PacketFlight getPacketFlight(String id){
		return em.createNamedQuery(PacketFlight.FIND_PACKETFLIGHT, PacketFlight.class).setParameter("id", id).getSingleResult();
	}
	
	private PacketDTO convertToDTO(Packet packet) {
		PacketDTO packetDTO = new PacketDTO();
		packetDTO.setCity(packet.getCity());
		packetDTO.setDescription(packet.getDescription());
		packetDTO.setStart(packet.getStart());
		packetDTO.setEnd(packet.getEnd());
		packetDTO.setPrice(packet.getPrice());
		packetDTO.setSpots(packet.getSpots());
		packetDTO.setEmployee(packet.getEmployee());
		packetDTO.setVisibility(packet.getVisibility());
		packetDTO.setHotel(packet.getHotel().getId());
		return packetDTO;
	}
	
	private PacketFlightDTO convertToDTO(PacketFlight packetFlight) {
		PacketFlightDTO packetFlightDTO = new PacketFlightDTO();
		packetFlightDTO.setId(packetFlight.getId());
		packetFlightDTO.setPacket(packetFlight.getPacket().getId());
		packetFlightDTO.setFlight(packetFlight.getFlight().getId());
		return packetFlightDTO;
	}



	@Override
	public List<String> getHotelByCity(String city) {
		List<String> someHotel= new ArrayList<String>();
		for(Hotel h: hotelByCity(city))
			someHotel.add(h.toString());
		return someHotel;
	}

	private List<Hotel> hotelByCity(String city){
		return em.createNamedQuery(Hotel.FIND_BY_CITY, Hotel.class).setParameter("city", city).getResultList();
	}



	@Override
	public void registerFlight(int departure, int arrival) {
		Flight departuref = em.createNamedQuery(Flight.FIND_FLIGHT, Flight.class).setParameter("id", departure).getSingleResult();
		Flight arrivalf = em.createNamedQuery(Flight.FIND_FLIGHT, Flight.class).setParameter("id", arrival).getSingleResult();
		Packet pack = em.createNamedQuery(Packet.FIND_PACKET, Packet.class).setParameter("id", packetID).getSingleResult();
		PacketFlight newPacketFlight1 = new PacketFlight(pack, departuref);
		PacketFlight newPacketFlight2 = new PacketFlight(pack, arrivalf);
		em.persist(newPacketFlight1);
		pack.addPacketFlight(newPacketFlight1);
		em.persist(newPacketFlight2);
		pack.addPacketFlight(newPacketFlight2);
	}



	@Override
	public void registerAttraction(List<Integer> list) {
		Packet pack = em.createNamedQuery(Packet.FIND_PACKET, Packet.class).setParameter("id", packetID).getSingleResult();
		List<Attraction> listAttractions = new ArrayList<Attraction>();
		for(Integer i: list){
			int val = i;
			listAttractions.add(em.createNamedQuery(Attraction.FIND_ATTRACTION, Attraction.class).setParameter("id", val).getSingleResult());
		}
		for (Attraction a: listAttractions){
			PacketAttraction p = new PacketAttraction(pack,a);
			em.persist(p);
			pack.addPacketAttraction(p);
			}
	}



	public int getPacketID() {
		return packetID;
	}



	public void setPacketID(int packetID) {
		this.packetID = packetID;
	}

	private List<Packet> findAllPersonalizedPacket(){
		return em.createNamedQuery(Packet.FIND_ALL, Packet.class).getResultList();
		
	}

	@Override
	public List<String> getEmployeePacket() {
		List<String> list = new ArrayList<String>();
		List<Packet> packet = em.createNamedQuery(Packet.FIND_ALL, Packet.class).getResultList();
	
		for (Packet p: packet){
			if(p.getEmployee().equals(context.getCallerPrincipal().getName())&&p.getVisibility())
			list.add(p.toString());
		}
		return list;
	}
	
	@Override
	public List<String> getAllPacket(){
		List<String> list = new ArrayList<String>();
		List<Packet> p = em.createNamedQuery(Packet.FIND_ALL, Packet.class).getResultList();
		for (Packet pa: p){
			if(pa.getVisibility())
			list.add(pa.toString());
		}
		return list;
	}
	
	@Override
	public List<Integer> getAllPacketId(){
			List<Integer> list = new ArrayList<Integer>();
			List<Packet> p = em.createNamedQuery(Packet.FIND_ALL, Packet.class).getResultList();
			for (Packet pa: p){
				list.add(pa.getId());
			}
			return list;
	}



	@Override
	public void remove(int removalID) {
		Packet p = em.createNamedQuery(Packet.FIND_PACKET, Packet.class).setParameter("id", removalID).getSingleResult();
		p.setVisibility(false);
	}



	@Override
	public List<String> getPacketByCity(String city) {
		List<Packet> packets = em.createNamedQuery(Packet.FIND_BY_CITY, Packet.class).setParameter("city", city).getResultList();
		List<String> list = new ArrayList<String>();
		for(Packet p: packets)
			list.add(p.toString());
		return list;
	}



	@Override
	public List<String> getFlightsFromPacket(int id2) {
		Packet p = em.createNamedQuery(Packet.FIND_PACKET, Packet.class).setParameter("id", id2).getSingleResult();
		List<PacketFlight> pa = p.getPacketFlights();
		List<String> list = new ArrayList<String>();
		for (PacketFlight a: pa){
			list.add(a.getFlight().toString());
		}
		return list;
	}



	@Override
	public List<String> getAttractionsFromPacket(int id2) {
		Packet p = em.createNamedQuery(Packet.FIND_PACKET, Packet.class).setParameter("id", id2).getSingleResult();
		List<PacketAttraction> pa = p.getPacketAttractions();
		List<String> list = new ArrayList<String>();
		for (PacketAttraction a: pa){
			list.add(a.getAttractionBean().toString());
		}
		return list;
	}



	@Override
	public String searchPersonalizedPacketById(int id2) {
		Packet p = em.createNamedQuery(Packet.FIND_PACKET, Packet.class).setParameter("id", id2).getSingleResult();
		return p.toString();
	}
	
}
